<template>
  <vxe-column type="checkbox" width="60" align="center" class="table-checkbox">
    <template #header="{ checked, indeterminate }">
      <span class="custom-checkbox" @click.stop="() => toggleAllCheckboxRow()">
        <i v-if="indeterminate" class="vxe-icon-square-minus-fill"></i>
        <i v-else-if="checked" class="vxe-icon-square-checked-fill"></i>
        <i v-else class="vxe-icon-checkbox-unchecked"></i>
      </span>
    </template>
    <template #checkbox="{ row, checked, indeterminate }">
      <span class="custom-checkbox" @click.stop="() => toggleCheckboxRow(row)">
        <i v-if="indeterminate" class="vxe-icon-square-minus-fill"></i>
        <i v-else-if="checked" class="vxe-icon-square-checked-fill"></i>
        <i v-else class="vxe-icon-checkbox-unchecked"></i>
      </span>
    </template>
  </vxe-column>
</template>

<script>
import { onMounted, watch } from 'vue';
import { get, isEqual } from 'lodash-es';

export default {
  name: 'table-checkbox',
  props: {
    modelValue: { default: undefined },
    valueField: { type: String, default: 'id' },
    VxeTableGetter: { type: Function, default: undefined },
  },
  setup(props, ctx) {
    let selectRowValues = [];

    onMounted(() => {
      watch(
        () => props.modelValue,
        (values) => {
          if (Array.isArray(values) && !isEqual(values, selectRowValues)) {
            values.forEach((value) => {
              toggleCheckboxRow({ [props.valueField]: value }, false);
            });
          }
        },
        { immediate: true }
      );
    });

    function output() {
      ctx.emit('update:modelValue', [...selectRowValues]);
      setTimeout(() => {
        ctx.emit('change', [...selectRowValues]);
      }, 0);
    }

    function getVxeTable(handle) {
      if (typeof props.VxeTableGetter === 'function') {
        const VxeTable = props.VxeTableGetter();
        if (VxeTable) {
          return handle(VxeTable, ...[].slice.apply(arguments, 1));
        } else {
          console.warn('VxeTableGetter got invalid table ref instance!');
        }
      }
    }

    function toggleSelectValue(value) {
      const index = selectRowValues.indexOf(value);
      if (index < 0) {
        selectRowValues.push(value);
      } else {
        selectRowValues.splice(index, 1);
      }
    }

    function toggleCheckboxRow(row, isOutput) {
      toggleSelectValue(get(row, props.valueField));
      getVxeTable((vxeTable, row) => {
        vxeTable.toggleCheckboxRow(row);
        selectRowValues = vxeTable.getCheckboxRecords(true);
      }, row);
      if (isOutput !== false) {
        output();
      }
    }

    function toggleAllCheckboxRow(isOutput) {
      selectRowValues.length = 0;
      getVxeTable((vxeTable) => vxeTable.toggleAllCheckboxRow());
      if (isOutput !== false) {
        output();
      }
    }

    return { toggleCheckboxRow, toggleAllCheckboxRow };
  },
};
</script>

<style scoped lang="less">
.table-checkbox {
  [class*='vxe-icon-success-circle'] {
    color: #1890ff;
    cursor: pointer;
  }
}
.table-checkbox-head:not(.disabled) {
  color: #1890ff;
  cursor: pointer;
}
.table-checkbox-head.disabled {
  color: #c0c0c0;
  cursor: not-allowed;
}
</style>
